/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is confidential property of Nordic
 * Semiconductor ASA.Terms and conditions of usage are described in detail
 * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 */

/** @file
* @brief Example project on GPIO usage to drive LEDs
* @defgroup gpio_example_pca10001 GPIO example
* @{
* @ingroup nrf_examples_pca10001
*
* @brief Example of GPIO output usage.
*
* This example shows how to configure GPIO pins as outputs which can also be used to drive LEDs.
* Each LED is set on one at a time and each state lasts 100 milliseconds.
*/

#include <stdbool.h>
#include <stdint.h>
#include "nrf_gpio.h"
#include "boards.h"

#if defined(BOARD_NRF6310)
  #define STATE_MASK   0x07
#elif defined(BOARD_PCA10001)
  #define STATE_MASK   0x01
#else
  #error "Board is not defined"
#endif


/** Initializes Timer 0 peripheral.
 */
static void timer0_init(void);
static uint_fast16_t timer0_cc0_period; /*!< Period between debouncer input reads. */
static uint8_t mTMR0_Flag=0;
#define TIMER0_PRESCALER (9UL) /*!< Timer 0 prescaler */
#define TIMER0_CLOCK (SystemCoreClock >> TIMER0_PRESCALER) /*!< Timer clock frequency */
#define MS_TO_TIMER0_TICKS(ms) ((1000000UL * ms) / (TIMER0_CLOCK)) /*!< Converts milliseconds to timer ticks */

/** Timer 0 peripheral interrupt handler.
 */
void TIMER0_IRQHandler(void)
{
  if ((NRF_TIMER0->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER0->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0))
  {
    NRF_TIMER0->EVENTS_COMPARE[0] = 0;
    NRF_TIMER0->CC[0] += timer0_cc0_period;
		mTMR0_Flag = 1;
  }
}

static void timer0_init(void)
{
  // Power on the TIMER0 peripheral
  NRF_POWER->PERPOWER |= (POWER_PERPOWER_TIMER0_Power << POWER_PERPOWER_TIMER0_Pos);

  // Wait for the power up
  while ((NRF_POWER->PERRDY & POWER_PERRDY_TIMER0_Msk) != (POWER_PERRDY_TIMER0_Ready << POWER_PERRDY_TIMER0_Pos))
  {
  }

  NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; // Set the timer in Timer Mode
  NRF_TIMER0->PRESCALER = TIMER0_PRESCALER;

  // Enable interrupt for COMPARE[0]
  NRF_TIMER0->INTENSET = (1UL << TIMER_INTENSET_COMPARE0_Pos);
  NRF_TIMER0->CC[0] = timer0_cc0_period;
  NRF_TIMER0->TASKS_START = 1; // Start clocks
}

/**
 * main() function
 * @return 0. int return type required by ANSI/ISO standard.
 */
int main(void)
{
		uint8_t output_state = 0;
		timer0_cc0_period = MS_TO_TIMER0_TICKS(250);	// 250ms interrupt
		timer0_init();

		NVIC_EnableIRQ(TIMER0_IRQn); // Enable Interrupt for the timer in the core
		__enable_irq();

		// Configure LED-pins as outputs
		nrf_gpio_range_cfg_output(LED_START, LED_STOP);

		while (true)
		{
			if (mTMR0_Flag==1)	// Timer0 Interrupt flag
			{
				mTMR0_Flag = 0;
				nrf_gpio_port_write(LED_PORT, 1 << (output_state + LED_OFFSET));
				output_state = (output_state + 1) & STATE_MASK;
			}
		}
	
}

/**
 *@}
 **/
